// File Name Decomposer :: Denis Yurin (c) 2011
#ifndef FILENAMEDECOMPRESSOR_H
#define FILENAMEDECOMPRESSOR_H

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

// fileName = baseFileName + <fileID> + <partSep> + <partID>
// fullFileName = path + baseFileName
// fullBaseFileName = path + baseFileName
using namespace std;

class FND {
	
	public:
		
		string path; 
		string baseFileName; 		
		string fileID; // file ID
		uint 	ifileID; 
		string partSep; // separation charecters f.e. _ for snap000_1
		string partID; // if file is splited then this is part ID
		uint 	ipartID;

		string fileName; // = baseFileName + <fileID> + <partSep> + <partID>
		string fullFileName; // = path + baseFileName
		string fullBaseFileName; // = path + baseFileName
		
		vector<string> dirList, dirList2; // ss list
		
		// Snapshot File Name Decompossing
		int decompose(string fileName){ 
			
			fullFileName = fileName;
			
			path = fileName.substr(0, fileName.find_last_of("/")+1);
			this->fileName = fileName.substr(fileName.find_last_of("/")+1, fileName.length());
			
			if (this->fileName.find_first_of("0123456789")==string::npos) { 
				partSep=fileID=partID=fullBaseFileName=baseFileName = ""; ifileID =ipartID= -1;
				dirList.erase(dirList.begin(), dirList.begin()+dirList.size());
				dirList2.erase(dirList2.begin(), dirList2.begin()+dirList2.size());
				return 0;
			}
			
			fullBaseFileName = fileName.substr(0, fileName.find_first_of("0123456789"));
			baseFileName = this->fileName.substr(0, this->fileName.find_first_of("0123456789"));
			
			
			dirList.erase(dirList.begin(), dirList.begin()+dirList.size());
			dirList2.erase(dirList2.begin(), dirList2.begin()+dirList2.size());
			
			string path_ = path.substr(0, path.find_last_of("/"));
			while ( path_.find_last_of("/") != string::npos) {
				dirList.push_back(path_);
				dirList2.push_back(path_.substr(path_.find_last_of("/")+1, path_.length())+"/");		
				path_=path_.substr(0, path_.find_last_of("/"));
			}
			
			// File ID Number
			string _fids = this->fileName.substr(this->fileName.find_first_of("0123456789"), this->fileName.length());
			fileID = _fids.substr(0, _fids.find_first_not_of("0123456789"));
			ifileID = atoi(fileID.c_str());
			
			// Part Number if it is exist
			if (_fids.find_first_not_of("0123456789")!=string::npos) {
				partSep = _fids.substr(_fids.find_first_not_of("0123456789"), _fids.find_last_not_of("0123456789")-2);  // it is not clear why -2 ??...
				partID = _fids.substr(_fids.find_last_not_of("0123456789")+1, _fids.length());  // it is not clear why -2 ??...
				ipartID = atoi(partID.c_str());
			} else {
				partID=partSep="";
				ipartID=0;
			}
			
			
			return 1;
		}
		
		// Print out decomposed information
		void print(){
			
			printf("\033[22;34mpath\033[22;30m: %s\n", path.c_str());
			printf("\033[22;34mfileName\033[22;30m: %s\n", fileName.c_str());
			printf("\033[22;34mfullBaseFileName\033[22;30m: %s\n", fullBaseFileName.c_str());
			printf("\033[22;34mbaseFileName\033[22;30m: %s\n", baseFileName.c_str());
			printf("\n");
			
			for (uint i = 0; i<dirList.size();i++)
			printf("\033[22;34mdirList[%u]\033[22;30m: %s\n", i, dirList[i].c_str());
			printf("\n");
			
			printf("\033[22;34mfileID\033[22;30m: %s\n", fileID.c_str());
			printf("\033[22;34mifileID\033[22;30m: \033[22;33m%u\033[22;30m\n", ifileID);
				
			
			if (partID=="") { 
				printf("\033[22;34mpartSep\033[22;30m: \033[22;37mn/a\033[22;30m\n");
				printf("\033[22;34mpartID\033[22;30m: \033[22;37mn/a\033[22;30m\n");
				printf("\033[22;34mipartID\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			} else {
				printf("\033[22;34mpartSep\033[22;30m: %s\n", partSep.c_str());
				printf("\033[22;34mpartID\033[22;30m: %s\n", partID.c_str());
				printf("\033[22;34mipartID\033[22;30m: \033[22;33m%u\033[22;30m\n", ipartID);
			}
			
		}
};

#endif